package com.melly.demo1.controller;

import com.alibaba.fastjson.JSONObject;
import com.melly.demo1.model.cluster.ClusterUser;
import com.melly.demo1.model.master.MasterUser;
import com.melly.demo1.service.cluster.ClusterUserService;
import com.melly.demo1.service.master.MasterUserService;
import com.melly.demo1.utils.EncryptionUtils;
import com.melly.demo1.utils.HttpClientUtils;
import com.melly.demo1.utils.MobileFormatUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.util.*;
import java.util.concurrent.*;

@RestController
@Slf4j
public class UserController {

    @Autowired
    private ClusterUserService clusterUserService;

    @Autowired
    private MasterUserService masterUserService;

    private static List<ClusterUser> list1 = new ArrayList<ClusterUser>();

    private static List<ClusterUser> list2 = new ArrayList<>();

    private static List<ClusterUser> list3 = new ArrayList<ClusterUser>();

    private static List<ClusterUser> list4 = new ArrayList<ClusterUser>();

    CountDownLatch count = new CountDownLatch(100000);


    List<String> existsMobile = new ArrayList<>();

    List<String> failMobile = new ArrayList<>();

    @RequestMapping("user/getCluster")
     public void getCluster() {
        List<ClusterUser> result = clusterUserService.getAll();
        List<String> inValidateMobile = new ArrayList<>();
        for(ClusterUser c : result){
            log.info("id=="+c.getId());
            Boolean flag = MobileFormatUtils.isMobileNO(c.getMobile());
            if(!flag){
                inValidateMobile.add(c.getMobile());
            }
        }
//        clusterUserService.updateCluster(existsMobile,"EXISTS");
        log.info("有:{}手机号是无效的",inValidateMobile.size());
        clusterUserService.delMobile(inValidateMobile);
//        return result;

    }

    @RequestMapping("/cal")
    public void calCount(){

        List<ClusterUser> result = clusterUserService.getAll();
        log.info("数据量:{}",result.size());
        list1 = result.subList(0,result.size()/4);
        log.info("list1=="+list1.size());
        list2 = result.subList((result.size()/4),(2*result.size()/4));
        list3 = result.subList((2*result.size()/4),(3*result.size()/4));
        list4 = result.subList((3*result.size()/4),result.size());
        log.info("list1="+list1.size()+" start=="+list1.get(0).getId());
        log.info("list2="+list2.size() +" start=="+list2.get(0).getId());
        log.info("list3="+list3.size() +" start=="+list3.get(0).getId());
        log.info("list4="+list4.size() +" start=="+list4.get(0).getId());

    }

    @RequestMapping("user/getMaster")
    public void getMaster() {
        EncryptionUtils t = new EncryptionUtils();
        t.init("CreditCloudRock");
        List<ClusterUser> result = clusterUserService.getAll();
        for(ClusterUser clusterUser : result){
            MasterUser user = new MasterUser();
            user.setId(UUID.randomUUID().toString());
            String mobile = "";
            try {
                mobile= t.encrypt(clusterUser.getMobile());

            } catch (GeneralSecurityException e) {
                e.printStackTrace();
            }
            user.setMobile(mobile);
            user.setLoginName("ajph_"+clusterUser.getMobile());
            user.setRegisterDate(new Date());
            System.out.println("user=="+user);
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("id",user.getId());
            map.put("date",user.getRegisterDate());
            map.put("loginName",user.getLoginName());
            map.put("mobile",clusterUser.getMobile());
            map.put("recordId",UUID.randomUUID().toString());
            try{
                masterUserService.addUser(user);
                masterUserService.addUserInfo(map);
                masterUserService.addAuth(map);
                masterUserService.addUserFund(map);
                masterUserService.addUserRecord(map);
            }catch(Exception e){
                log.error("添加用户出错了:"+e.getMessage());
            }

        }
    }

    boolean flag = false;

    @RequestMapping("user/test")
    public void job(){
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        List<ClusterUser> result = clusterUserService.getAll();
        log.info("数据量:{}",result.size());
        list1 = result.subList(0,result.size()/4);
        log.info("list1=="+list1.size());
        list2 = result.subList((result.size()/4),(2*result.size()/4));
        list3 = result.subList((2*result.size()/4),(3*result.size()/4));
        list4 = result.subList((3*result.size()/4),result.size());
        log.info("list1="+list1.size()+" start=="+list1.get(0));
        log.info("list2="+list2.size() +" start=="+list2.get(0));
        log.info("list3="+list3.size() +" start=="+list3.get(0));
        log.info("list4="+list4.size() +" start=="+list4.get(0));
        FutureTask<JSONObject> futureTask1 = new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataScheduled(result);
            }
        });

        FutureTask<JSONObject> futureTask2 = new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataScheduled(list2);
            }
        });

        FutureTask<JSONObject> futureTask3= new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataScheduled(list3);
            }
        });

        FutureTask<JSONObject> futureTask4= new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataScheduled(list4);
            }
        });

        executorService.submit(futureTask1);

        executorService.submit(futureTask2);

        executorService.submit(futureTask3);

        executorService.submit(futureTask4);


    }


    public JSONObject pushDataScheduled( List<ClusterUser> list){
        String name = Thread.currentThread().getName();
        log.info("线程:{} 开始工作了，开始时间:{}",name, DateFormat.getDateInstance());

        for(ClusterUser c : list){
            log.info("线程:{} 准备开始处理第:{} 条数据",name,c.getId());
            Map<String,String> map = new HashMap<String,String>();
            map.put("mobile",c.getMobile());
            map.put("password","feng123456");
            map.put("relSource","tghda");
            String url = "https://www.cmiinv.com/api/v2/users/simpleRegister";
//            String url = "http://10.17.5.102/api/v2/users/simpleRegister";
            try {

                String result = HttpClientUtils.send(url,map,"UTF-8");
                JSONObject json = JSONObject.parseObject(result);
                if(!(boolean)json.get("success")){
                    log.info("手机号:{} 注册失败:{}",c.getMobile(),json.get("error"));
                    JSONObject errorMessage = (JSONObject) json.getJSONArray("error").get(0);
                    log.info("errorMessage：{}",errorMessage);
                    if("LOGINNAME_EXISTS".equals(errorMessage.getString("message")) ||
                            "MOBILE_USED".equals(errorMessage.getString("message"))){
                        existsMobile.add(c.getMobile());
                    }else{
                        failMobile.add(c.getMobile());
                    }
                }
            }catch (Exception e){
                failMobile.add(c.getMobile());
                log.info("出现异常:{}",e.getMessage());
            }
        }
        if(existsMobile.size() > 1){
            clusterUserService.updateCluster(existsMobile,"EXISTS");
        }
        if(failMobile.size() >1){
            clusterUserService.updateCluster(failMobile,"FAILED");
        }

        log.info("线程:{} 完成工作，失败的有：{}条  已经存在的有:{}条 结束时间:{}",Thread.currentThread().getName(),
                failMobile.size(),existsMobile.size(), DateFormat.getDateInstance());
        flag = true;
        return null;
    }


    @RequestMapping("user/update")
    public void update(){
        clusterUserService.updateCluster(existsMobile,"EXISTS");
        clusterUserService.updateCluster(failMobile,"FAILED");

    }

    @RequestMapping("user/insertKyd")
    public void inserKyd(){
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        List<ClusterUser> result = clusterUserService.getAll();
        log.info("数据量:{}",result.size());
        list1 = result.subList(0,result.size()/4);
        log.info("list1=="+list1.size());
        list2 = result.subList((result.size()/4),(2*result.size()/4));
        list3 = result.subList((2*result.size()/4),(3*result.size()/4));
        list4 = result.subList((3*result.size()/4),result.size());
        log.info("list1="+list1.size()+" start=="+list1.get(0));
        log.info("list2="+list2.size() +" start=="+list2.get(0));
        log.info("list3="+list3.size() +" start=="+list3.get(0));
        log.info("list4="+list4.size() +" start=="+list4.get(0));
        FutureTask<JSONObject> futureTask1 = new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataToKyd(result);
            }
        });

        FutureTask<JSONObject> futureTask2 = new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataToKyd(list2);
            }
        });

        FutureTask<JSONObject> futureTask3= new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataToKyd(list3);
            }
        });

        FutureTask<JSONObject> futureTask4= new FutureTask<JSONObject>(new Callable<JSONObject>() {
            @Override
            public JSONObject call() throws Exception {
                return pushDataToKyd(list4);
            }
        });

        executorService.submit(futureTask1);

        executorService.submit(futureTask2);

        executorService.submit(futureTask3);

        executorService.submit(futureTask4);
    }

    private JSONObject pushDataToKyd(List<ClusterUser> list) {
        String name = Thread.currentThread().getName();
        log.info("线程:{} 开始工作了，开始时间:{}",name, DateFormat.getDateInstance());

        for(ClusterUser c : list){
            log.info("线程:{} 准备开始处理第:{} 条数据",name,c.getId());
            Map<String,String> map = new HashMap<String,String>();
            map.put("mobile",c.getMobile());
            map.put("password","feng123456");
            map.put("regSource","tghda");
            String url = "http://app1.kuyaodai.com/kyd_api//app/quick/register.html";
//            String url = "http://10.17.5.102/api/v2/users/simpleRegister";
            try {

                String result = HttpClientUtils.send(url,map,"UTF-8");

            }catch (Exception e){
                failMobile.add(c.getMobile());
                log.info("出现异常:{}",e.getMessage());
            }
        }

        return null;
    }

    //    @Scheduled(cron = "00 35 * * * ?")
    public void test(){
        EncryptionUtils t = new EncryptionUtils();
        t.init("CreditCloudRock");
        List<ClusterUser> result = clusterUserService.getAll();
        int count = 0;
        for(ClusterUser clusterUser : result){
            MasterUser user = new MasterUser();
            user.setId(UUID.randomUUID().toString());
            String mobile = "";
            try {
                mobile= t.encrypt(clusterUser.getMobile());

            } catch (GeneralSecurityException e) {
                e.printStackTrace();
            }
            user.setMobile(mobile);
            user.setLoginName("ajph_"+clusterUser.getMobile());
            user.setRegisterDate(new Date());
            System.out.println("user=="+user);
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("id",user.getId());
            map.put("date",user.getRegisterDate());
            map.put("loginName",user.getLoginName());
            map.put("mobile",clusterUser.getMobile());
            map.put("recordId",UUID.randomUUID().toString());
            try{
                masterUserService.addUser(user);
                masterUserService.addUserInfo(map);
                masterUserService.addAuth(map);
                masterUserService.addUserFund(map);
                masterUserService.addUserRecord(map);
                count++;
            }catch(Exception e){
                log.error("添加用户:{},出错了:{}",clusterUser.getMobile(),e.getMessage());
                continue;
            }

        }
        log.info("数据导入完毕,成功:{}条",count);
    }

    public static List<List<ClusterUser>> averageAssign( List<ClusterUser> source, int splitItemNum )
    {
        List<List<ClusterUser>> result = new ArrayList<List<ClusterUser>>();

        if ( source != null && source.size() > 0 && splitItemNum > 0 ){
            if ( source.size() <= splitItemNum ){
                // 源List元素数量小于等于目标分组数量
                result.add( source );
            }else{
                // 计算拆分后list数量
                int splitNum = ( source.size() % splitItemNum == 0 ) ? ( source.size() / splitItemNum ) : ( source.size() / splitItemNum + 1 );

                List<ClusterUser> value = null;
                for ( int i = 0; i < splitNum; i++ ){
                    if ( i < splitNum - 1 ){
                        if(i == 0){
                            list1 = source.subList( i * splitItemNum, ( i + 1 ) * splitItemNum);
                            result.add(list1);
                        }
                        if(i ==1){
                            list2 =source.subList( i * splitItemNum, ( i + 1 ) * splitItemNum );
                            result.add(list2);
                        }

                    }else{
                        // 最后一组
                        list3 = source.subList( i * splitItemNum, source.size());
                        result.add(list3);
                    }
                }
            }
        }

        return result;
    }

}
